package cn.edu.nju.software.cdiy.action.user.all;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.edu.nju.software.cdiy.algorithm.assessor.ApplicationScopeAssessor;
import cn.edu.nju.software.cdiy.algorithm.assessor.ApplicationScopeMessager;
import cn.edu.nju.software.cdiy.algorithm.assessor.Optimizer;
import cn.edu.nju.software.cdiy.algorithm.assessor.PerformanceAssessor;
import cn.edu.nju.software.cdiy.algorithm.assessor.PerformanceMessager;
import cn.edu.nju.software.cdiy.bean.HardwareSet;
import cn.edu.nju.software.cdiy.service.Service;
import cn.edu.nju.software.cdiy.util.Constant;
import cn.edu.nju.software.cdiy.util.Item;
import cn.edu.nju.software.cdiy.util.SortType;
import cn.edu.nju.software.cdiy.util.SortWay;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;

@SuppressWarnings("serial")
public class DIYAction extends ActionSupport implements Preparable {

	private static String[] PAGES_NAME = {"mainboard_list", "cpu_list", "memory_list", "disk_list", "graphics_list", "chassis_list", "power_list", 
										"radiator_list", "driver_list", "monitor_list", "soundbox_list", "soundcard_list", "networkcard_list"};
	private List<Service<?>> serviceList;
	private PerformanceAssessor performanceAssessor;
	private ApplicationScopeAssessor applicationScopeAssessor;
	private Optimizer optimizer;
	private List<Map<String, List<Item>>> filterList = new ArrayList<Map<String, List<Item>>>(Constant.HARDWARE_AMOUNT);;
	private Map<String, Integer> selectedConditions;
	private List<?> result;
	private int resultAmount;
	private String partPage;
	private PerformanceMessager performanceMessager;
	private ApplicationScopeMessager applicationScopeMessager;
	private String optimizationMessage;
	private int category = 0;
	private int sortOrder = Constant.TIME;
	private int pageNum = 1;
	private List<String> hardwares;
	private HardwareSet hardwareSet;

	public void setServiceList(List<Service<?>> serviceList) {
		this.serviceList = serviceList;
	}
	
	public void setPerformanceAssessor(PerformanceAssessor performanceAssessor) {
		this.performanceAssessor = performanceAssessor;
	}

	public void setApplicationScopeAssessor(ApplicationScopeAssessor applicationScopeAssessor) {
		this.applicationScopeAssessor = applicationScopeAssessor;
	}

	public void setOptimizer(Optimizer optimizer) {
		this.optimizer = optimizer;
	}

	public List<Map<String, List<Item>>> getFilterList() {
		return filterList;
	}

	public Map<String, Integer> getSelectedConditions() {
		return selectedConditions;
	}

	public void setSelectedConditions(Map<String, Integer> selectedConditions) {
		this.selectedConditions = selectedConditions;
	}

	public List<?> getResult() {
		return result;
	}

	public int getResultAmount() {
		return resultAmount;
	}

	public String getPartPage() {
		return partPage;
	}

	public PerformanceMessager getPerformanceMessager() {
		return performanceMessager;
	}

	public ApplicationScopeMessager getApplicationScopeMessager() {
		return applicationScopeMessager;
	}

	public String getOptimizationMessage() {
		return optimizationMessage;
	}

	public int getCategory() {
		return category;
	}

	public void setCategory(int category) {
		this.category = category;
	}

	public void setSortOrder(int sortOrder) {
		this.sortOrder = sortOrder;
	}

	public void setPageNum(int pageNum) {
		this.pageNum = pageNum;
	}

	public List<String> getHardwares() {
		return hardwares;
	}

	public void setHardwares(List<String> hardwares) {
		this.hardwares = hardwares;
	}

	private Map<String, List<Integer>> convertMap() {
		Map<String, List<Integer>> selectedListMap = null;
		if (selectedConditions!=null && selectedConditions.size()!=0) {
			selectedListMap = new HashMap<String, List<Integer>>();
			for (String key : selectedConditions.keySet()) {
				List<Integer> list = new ArrayList<Integer>();
				list.add(selectedConditions.get(key));
				selectedListMap.put(key, list);
			}
		}
		return selectedListMap;
	}
	
	private List<?> filter(Service<?> service) {
		Map<String, List<Integer>> selectedListMap = convertMap();
		List<?> result = null;
		switch (sortOrder) {
		case Constant.TIME:
			result = service.filter(pageNum, selectedListMap, SortType.NEW, SortWay.DESC, hardwareSet);
			break;
		case Constant.SALE:
			result = service.filter(pageNum, selectedListMap, SortType.HOT, SortWay.DESC, hardwareSet);
			break;
		case Constant.PRICE_LOW:
			result = service.filter(pageNum, selectedListMap, SortType.PRICE, SortWay.ASC, hardwareSet);
			break;
		case Constant.PRICE_HIGH:
			result = service.filter(pageNum, selectedListMap, SortType.PRICE, SortWay.DESC, hardwareSet);
			break;
		case Constant.SCORE_USER:
			result = service.filter(pageNum, selectedListMap, SortType.W_SCORE, SortWay.DESC, hardwareSet);
			break;
		case Constant.SCORE_PRO:
			result = service.filter(pageNum, selectedListMap, SortType.Z_SCORE, SortWay.DESC, hardwareSet);
			break;
		//Constant.PERFORMANCE
		default:
			result = service.filter(pageNum, selectedListMap, SortType.PERFORMANCE, SortWay.DESC, hardwareSet);
			break;
		}
		selectedListMap = null;
		return result;
	}

	@Override
	public void prepare() throws Exception {
		if (selectedConditions != null) {
			selectedConditions.clear();
		}
		if (hardwares != null) {
			hardwares.clear();
		}
		performanceMessager = null;
		applicationScopeMessager = null;
		optimizationMessage = null;
	}

	@Override
	public String execute() throws Exception {
		hardwareSet = null;
		if (result == null) {
			for(Service<?> service : serviceList) {
				filterList.add(service.getFilterBoard());
			}
		}
		category = 0;
		sortOrder = Constant.TIME;
		pageNum = 1;
		Service<?> mainBoardService = serviceList.get(0);
		result = filter(mainBoardService);
		resultAmount = mainBoardService.getFilterResultLength(convertMap(), hardwareSet);
		return SUCCESS;
	}
	
	public String loadPart() throws Exception {
		Service<?> service = serviceList.get(category);
		result = filter(service);
		resultAmount = service.getFilterResultLength(convertMap(), hardwareSet);
		partPage = PAGES_NAME[category];
		return SUCCESS;
	}
	
	public String getTips() throws Exception {
		hardwareSet = new HardwareSet();
		if (!hardwares.get(0).equals("0")) {
			String[] splitArray = hardwares.get(0).split("@");
			hardwareSet.setMainBoard(Integer.parseInt(splitArray[0]));
		}
		if (!hardwares.get(1).equals("0")) {
			String[] splitArray = hardwares.get(1).split("@");
			hardwareSet.setCpu(Integer.parseInt(splitArray[0]));
		}
		if (!hardwares.get(2).equals("0")) {
			String[] splitArray = hardwares.get(2).split("@");
			hardwareSet.setMemory(Integer.parseInt(splitArray[0]));
			hardwareSet.setMemoryNum(Integer.parseInt(splitArray[1]));
		}
		if (!hardwares.get(3).equals("0")) {
			String[] splitArray = hardwares.get(3).split("@");
			hardwareSet.setDisk(Integer.parseInt(splitArray[0]));
			hardwareSet.setDiskNum(Integer.parseInt(splitArray[1]));
		}
		if (!hardwares.get(4).equals("0")) {
			String[] splitArray = hardwares.get(4).split("@");
			hardwareSet.setGraphics(Integer.parseInt(splitArray[0]));
		}
		if (!hardwares.get(5).equals("0")) {
			String[] splitArray = hardwares.get(5).split("@");
			hardwareSet.setChassis(Integer.parseInt(splitArray[0]));
		}
		if (!hardwares.get(6).equals("0")) {
			String[] splitArray = hardwares.get(6).split("@");
			hardwareSet.setPower(Integer.parseInt(splitArray[0]));
		}
		if (!hardwares.get(7).equals("0")) {
			String[] splitArray = hardwares.get(7).split("@");
			hardwareSet.setRadiator(Integer.parseInt(splitArray[0]));
		}
		if (!hardwares.get(8).equals("0")) {
			String[] splitArray = hardwares.get(8).split("@");
			hardwareSet.setDriver(Integer.parseInt(splitArray[0]));
		}
		if (!hardwares.get(9).equals("0")) {
			String[] splitArray = hardwares.get(9).split("@");
			hardwareSet.setMonitor(Integer.parseInt(splitArray[0]));
		}
		if (!hardwares.get(10).equals("0")) {
			String[] splitArray = hardwares.get(10).split("@");
			hardwareSet.setSoundBox(Integer.parseInt(splitArray[0]));
		}
		if (!hardwares.get(11).equals("0")) {
			String[] splitArray = hardwares.get(11).split("@");
			hardwareSet.setSoundCard(Integer.parseInt(splitArray[0]));
		}
		if (!hardwares.get(12).equals("0")) {
			String[] splitArray = hardwares.get(12).split("@");
			hardwareSet.setNetworkAdapter(Integer.parseInt(splitArray[0]));
		}
		performanceMessager = performanceAssessor.generateAssess(hardwareSet);
		applicationScopeMessager = applicationScopeAssessor.generateAssess(hardwareSet);
		optimizationMessage = optimizer.getOptimizeSuggestion(hardwareSet);
		return SUCCESS;
	}
	
}
